<template>
    <el-dialog v-model="visible" :title="title" :width="width" :fullscreen="fullscreen" :top="top" :modal="modal"
        :modal-class="modalClass" :append-to-body="appendToBody" :lock-scroll="lockScroll" :custom-class="customClass"
        :open-delay="openDelay" :close-delay="closeDelay" :close-on-click-modal="closeOnClickModal"
        :close-on-press-escape="closeOnPressEscape" :show-close="showClose" :before-close="handleBeforeClose"
        :center="center" :align-center="alignCenter" :destroy-on-close="destroyOnClose" :draggable="draggable"
        @open="handleOpen" @opened="handleOpened" @close="handleClose" @closed="handleClosed">
        <!-- 自定义标题 -->
        <template v-if="$slots.title" #header>
            <slot name="title" />
        </template>

        <!-- 主要内容 -->
        <div class="modal-content">
            <!-- 确认对话框内容 -->
            <div v-if="type === 'confirm'" class="confirm-content">
                <div class="confirm-icon">
                    <el-icon v-if="confirmType === 'warning'" class="warning-icon">
                        <WarningFilled />
                    </el-icon>
                    <el-icon v-else-if="confirmType === 'error'" class="error-icon">
                        <CircleCloseFilled />
                    </el-icon>
                    <el-icon v-else-if="confirmType === 'success'" class="success-icon">
                        <CircleCheckFilled />
                    </el-icon>
                    <el-icon v-else class="info-icon">
                        <InfoFilled />
                    </el-icon>
                </div>
                <div class="confirm-message">
                    <div class="message-title">{{ confirmTitle || title }}</div>
                    <div v-if="confirmMessage" class="message-content">{{ confirmMessage }}</div>
                </div>
            </div>

            <!-- 表单内容 -->
            <div v-else-if="type === 'form'" class="form-content">
                <DynamicForm v-if="formConfig" ref="formRef" v-model="formData" :config="formConfig"
                    :label-width="formLabelWidth" :label-position="formLabelPosition" :size="formSize"
                    :show-buttons="false" @submit="handleFormSubmit" />
                <slot v-else name="form" :form-data="formData" />
            </div>

            <!-- 自定义内容 -->
            <div v-else class="custom-content">
                <slot :data="data" />
            </div>
        </div>

        <!-- 底部操作按钮 -->
        <template #footer>
            <div class="modal-footer">
                <slot name="footer" :loading="loading" :confirm="handleConfirm" :cancel="handleCancel">
                    <el-button v-if="showCancelButton" @click="handleCancel">
                        {{ cancelButtonText }}
                    </el-button>
                    <el-button v-if="showConfirmButton" type="primary" :loading="loading" @click="handleConfirm">
                        {{ confirmButtonText }}
                    </el-button>
                </slot>
            </div>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
/**
 * 模态对话框组件
 * @author Wu.Liang
 * @description 支持新增、编辑、确认等模态对话框功能
 */
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
    WarningFilled,
    CircleCloseFilled,
    CircleCheckFilled,
    InfoFilled
} from '@element-plus/icons-vue'
import DynamicForm from './DynamicForm.vue'
import type { FormItemConfig } from './DynamicForm.vue'
import { showWarning } from '@/utils/message'

interface Props {
    // 是否显示
    modelValue: boolean
    // 对话框标题
    title?: string
    // 对话框类型
    type?: 'custom' | 'form' | 'confirm'
    // 对话框宽度
    width?: string | number
    // 是否全屏
    fullscreen?: boolean
    // 距离顶部位置
    top?: string
    // 是否显示遮罩
    modal?: boolean
    // 遮罩样式类
    modalClass?: string
    // 是否插入到body
    appendToBody?: boolean
    // 是否锁定滚动
    lockScroll?: boolean
    // 自定义样式类
    customClass?: string
    // 打开延时
    openDelay?: number
    // 关闭延时
    closeDelay?: number
    // 点击遮罩是否关闭
    closeOnClickModal?: boolean
    // 按ESC是否关闭
    closeOnPressEscape?: boolean
    // 是否显示关闭按钮
    showClose?: boolean
    // 是否居中布局
    center?: boolean
    // 是否水平垂直居中
    alignCenter?: boolean
    // 关闭时销毁
    destroyOnClose?: boolean
    // 是否可拖拽
    draggable?: boolean

    // 确认对话框相关
    confirmType?: 'info' | 'success' | 'warning' | 'error'
    confirmTitle?: string
    confirmMessage?: string

    // 表单相关
    formConfig?: FormItemConfig[]
    formData?: Record<string, any>
    formLabelWidth?: string
    formLabelPosition?: 'left' | 'right' | 'top'
    formSize?: 'large' | 'default' | 'small'

    // 按钮配置
    showConfirmButton?: boolean
    showCancelButton?: boolean
    confirmButtonText?: string
    cancelButtonText?: string

    // 加载状态
    loading?: boolean

    // 关闭前回调
    beforeClose?: (done: () => void) => void

    // 传递数据
    data?: any
}

const props = withDefaults(defineProps<Props>(), {
    type: 'custom',
    width: '50%',
    fullscreen: false,
    top: '15vh',
    modal: true,
    appendToBody: false,
    lockScroll: true,
    openDelay: 0,
    closeDelay: 0,
    closeOnClickModal: true,
    closeOnPressEscape: true,
    showClose: true,
    center: false,
    alignCenter: false,
    destroyOnClose: false,
    draggable: false,
    confirmType: 'warning',
    formLabelWidth: '100px',
    formLabelPosition: 'right',
    formSize: 'default',
    showConfirmButton: true,
    showCancelButton: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    loading: false
})

const emit = defineEmits<{
    'update:modelValue': [visible: boolean]
    'confirm': [data?: any]
    'cancel': []
    'open': []
    'opened': []
    'close': []
    'closed': []
}>()

const formRef = ref()
const formData = ref<Record<string, any>>({})

// 计算属性
const visible = computed({
    get: () => props.modelValue,
    set: (value) => emit('update:modelValue', value)
})

// 监听表单数据变化
watch(() => props.formData, (newValue) => {
    if (newValue) {
        formData.value = { ...newValue }
    }
}, { immediate: true, deep: true })

// 事件处理
const handleOpen = () => {
    emit('open')
}

const handleOpened = () => {
    emit('opened')
}

const handleClose = () => {
    emit('close')
}

const handleClosed = () => {
    // 重置表单数据
    if (props.type === 'form') {
        formData.value = {}
    }
    emit('closed')
}

const handleBeforeClose = (done: () => void) => {
    if (props.beforeClose) {
        props.beforeClose(done)
    } else {
        done()
    }
}

const handleConfirm = async() => {
    if (props.type === 'form') {
        // 表单验证
        if (formRef.value) {
            try {
                await formRef.value.validate()
                emit('confirm', formData.value)
            } catch (error) {
                showWarning('请检查表单填写是否正确')
                return
            }
        } else {
            emit('confirm', formData.value)
        }
    } else {
        emit('confirm', props.data)
    }
}

const handleCancel = () => {
    emit('cancel')
    visible.value = false
}

const handleFormSubmit = (data: Record<string, any>) => {
    emit('confirm', data)
}

// 暴露方法
const validate = () => {
    return formRef.value?.validate()
}

const resetFields = () => {
    formRef.value?.resetFields()
}

const clearValidate = () => {
    formRef.value?.clearValidate()
}

defineExpose({
    validate,
    resetFields,
    clearValidate
})
</script>

<style lang="scss" scoped>
.modal-content {
    .confirm-content {
        display: flex;
        align-items: flex-start;
        padding: 10px 0;

        .confirm-icon {
            margin-right: 16px;

            .warning-icon {
                color: var(--el-color-warning);
                font-size: 24px;
            }

            .error-icon {
                color: var(--el-color-danger);
                font-size: 24px;
            }

            .success-icon {
                color: var(--el-color-success);
                font-size: 24px;
            }

            .info-icon {
                color: var(--el-color-info);
                font-size: 24px;
            }
        }

        .confirm-message {
            flex: 1;

            .message-title {
                font-size: 16px;
                font-weight: 600;
                color: var(--el-text-color-primary);
                margin-bottom: 8px;
            }

            .message-content {
                font-size: 14px;
                color: var(--el-text-color-regular);
                line-height: 1.6;
            }
        }
    }

    .form-content {
        padding: 10px 0;
    }

    .custom-content {
        // 自定义内容样式
    }
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
}
</style>

<style lang="scss">
// 全局样式覆盖
.el-dialog {
    border-radius: 8px;

    .el-dialog__header {
        padding: 20px 20px 10px;
        border-bottom: 1px solid var(--el-border-color-lighter);

        .el-dialog__title {
            font-size: 16px;
            font-weight: 600;
        }
    }

    .el-dialog__body {
        padding: 20px;
    }

    .el-dialog__footer {
        padding: 10px 20px 20px;
        border-top: 1px solid var(--el-border-color-lighter);
    }
}
</style>
